#pragma once
#include<memory>
#include<iostream>
#include"mytcp.hpp"
#include"Daemon.hpp"
#include<sys/wait.h>
#include<functional>
using ioservice_t =function<void(shared_ptr<Socket>& sock,Addr& client)>;
class tcpserver
{
public:
    tcpserver(uint16_t port,ioservice_t t)
    :_port(port)
    ,_t(t)
    ,_listenptr(std::make_unique<TcpSocket>())
    ,_isrunning(false)
    {
        _listenptr->BuildListenMethod(_port);
    }
    void Start()
    {
        daemon(0,0);
        _isrunning=true;
        while(_isrunning)
        {
            Addr client(_port);
            auto sock=_listenptr->Accept(&client);
            if(sock==nullptr)
            {
                exit(Sock::accepterr);
            }
            LOG(LogLevel::DEBUG)<<"Accept成功";
            //创建进程
            pid_t id=fork();
            if(id<0)
            {
                //进程创建失败
                LOG(LogLevel::WARNING)<<"进程创建失败";
                continue;
            }
            else if(id==0)
            {
                //子进程
                //则创建孙子进程,关闭不需要的文件描述符
                _listenptr->Close();
                pid_t p=fork();
                if(p>0)
                {
                    exit(ok);
                }
                //开始服务
                _t(sock,client);
            }
            else
            {
                //父进程
                sock->Close();
                int n=waitpid(id,nullptr,0);
            }
        }
        _isrunning=false;
    }
    ~tcpserver()
    {}
private:
    uint16_t _port;
    std::unique_ptr<Socket> _listenptr;
    bool _isrunning;
    ioservice_t _t;
};